import pgzrun
from vec import *
import random
import time

WIDTH = 600
HEIGHT = 440

BACK_COLOR = (0, 0, 0)
PEN_COLOR = (0, 200, 0)

lastTime = time.time()
deltaTime = 0

rcHeight = [100, 200, 120, 80, 50, 150, 20, 160, 90, 130]
n = len(rcHeight)
rcWidth = 20
space = 10
pspd = 2

class MyRect:
    def __init__(self, lb_x, lb_y, h, clr):
        self.pos = Vec2(lb_x, lb_y)
        self.h = h
        self.clr = clr
        self.p = 0.0
        self.curState = 0   # 0: 静止，1: 移动
        self.start_pt = Vec2(0, 0)
        self.end_pt = Vec2(0, 0)

    def StartMove(self, end_pt):
        if self.curState == 1:
            return

        self.curState = 1
        self.p = 0
        self.start_pt = self.pos
        self.end_pt = end_pt

    def Move(self):
        has_finished = False

        self.p += pspd * deltaTime

        if self.p > 1.0:    
            self.p = 1.0
            has_finished = True

        self.pos = self.start_pt * (1 - self.p) + self.end_pt * self.p

        return has_finished

    def Update(self):
        if self.curState == 1:
            if self.Move() == True:
                self.curState = 0

    def Draw(self):
        rc = Rect((self.pos.x, self.pos.y - self.h), (rcWidth, self.h))
        screen.draw.filled_rect(rc, self.clr)

startX = 150
iter = startX
rcList = []

range_queue = []
range_queue.append((0, len(rcHeight) - 1))

i = 0
j = 0

t = 0

isSortingFinished = False
sortingState = 0 # 0: 交换数据，1: 移动矩形

for item in rcHeight:
    r = random.randint(50, 200)
    g = random.randint(50, 200)
    b = random.randint(50, 200)
    rcList.append(MyRect(iter, HEIGHT / 2, item, (r, g, b)))
    iter += rcWidth
    iter += space

def do_swap(i, j):
    global rcHeight, rcList
    
    rcList[i].StartMove(rcList[j].pos)
    rcList[j].StartMove(rcList[i].pos)
    rcHeight[i], rcHeight[j] = rcHeight[j], rcHeight[i]
    rcList[i], rcList[j] = rcList[j], rcList[i]
    return True

sorting_step = 0
left, right = range_queue[0]
def update():
    global lastTime, deltaTime, isSortingFinished, sortingState, i, j
    global range_queue, sorting_step, t, left, right
    curTime = time.time()
    deltaTime = curTime - lastTime
    lastTime = curTime

    if isSortingFinished == True:
        return

    if sortingState == 0:
        if len(range_queue) == 0:
            isSortingFinished = True
        else:
            if sorting_step == 0:
                left, right = range_queue[0]
                i = left
                j = right
                t = left

                sorting_step = 1
            elif sorting_step == 1:
                if i == j:
                    do_swap(t, i)
                    range_queue = range_queue[1:]
                    if left < i - 1:
                        range_queue.append((left, i - 1))
                    
                    if i + 1 < right:
                        range_queue.append((i + 1, right))
                    sorting_step = 0
                    sortingState = 1
                else:
                    while(rcHeight[j] >= rcHeight[t] and i < j):
                        j -= 1
                    while(rcHeight[i] <= rcHeight[t] and i < j):
                        i += 1
                    if i < j:
                        do_swap(i, j)
                        sortingState = 1
    else:
        allStoped = True
        for rc  in rcList:
            rc.Update()
            if rc.curState == 1:
                allStoped = False

        if allStoped == True:
            sortingState = 0

def draw():
    screen.clear()
    screen.fill(BACK_COLOR)
    screen.draw.line((0, HEIGHT / 2), (WIDTH, HEIGHT / 2), PEN_COLOR)
    for rc in rcList:
        rc.Draw()

pgzrun.go()